<?php
/*
 * @@Copyright (C), 2021-2022: 恒盛时代
 * @Author: zhouzhou
 * @Date: 2021/11/24
 * @Description: 登录相关的
 */

namespace App\Http\Controllers\Api;

use App\Http\Controllers\WebApi\Business\ConfigBusiness;
use App\Jobs\RegisterTask;
use App\Services\Huanxin\UserServices;
use App\Services\RongCloud\UserService as RongUserService;
use App\Services\Netease\UserServices as NeteaseUserService;
use Illuminate\Routing\Controller;
use Illuminate\Support\Facades\Log;
use PhpOffice\PhpSpreadsheet\Shared\OLE\PPS;
use function Composer\Autoload\includeFile;
use Illuminate\Support\Facades\Auth;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Validator;
use App\Models\User;
use Gregwar\Captcha\CaptchaBuilder;
use Gregwar\Captcha\PhraseBuilder;
use App\Models\Verification;
use Overtrue\EasySms\EasySms;
use App\Models\ImDevice;
use App\Models\ImUserCondition;
use App\Services\Configs\DefaultService;

use Illuminate\Support\Facades\Redis;





class AuthController
{

    /**
     * @desc 用户注册
     * @param Request $request
     * @return mixed
     * @author zhouzhou
     * @time 2021/11/24 17:15
     */
    public function register(Request $request, user $userModel)
    {

        $input = $request->all();
        $messages = [
            'phone.required' => '手机号不能为空',
            'phone.max' => '手机号最大为11位字符',
            'phone.min' => '手机号最小为11位字符',
            'password.required' => '密码不能为空',
            'password.min' => '密码最少为6位字符',
        ];
        $validator = Validator::make($input, [
            'phone' => 'required|string|max:11|min:11',
            'password' => 'required|string|min:6',
        ], $messages);

        if($validator->fails())
        {
            return errBack($validator->errors()->first(), 400);
        }

        // 判断手机号是否存在
        $areaCode = $input['area_code'] ?? 86;
        $user = $userModel->where(['phone'=>$input['phone']])->first();
        if ($user && $user->area_code != $areaCode)
        {
            return errBack('请选择正确的区号');
        }

        $input['password'] = bcrypt($input['password']);
        // $user = User::create($input);
        $user->update(['nickname' => 'im'.$user->id, 'password'=>$input['password']]);
        if($user !== false)
        {
            Redis::set("user_set_{$user->id}", 1);
            return okBack($user);
        }

        return errBack('注册失败');
    }

    /**
     * @desc 短信验证码登录
     * @param Request $request
     * @return mixed
     * @author zhouzhou
     * @time 2021/11/24 17:15
     */
    public function smsLogin(Request $request, User $userModel, ImDevice $ImDeviceModel)
    {
        $input = $request->all();
        $messages = [
            'phone.required' => '手机号不能为空',
            'phone.max' => '手机号最大为11位字符',
            'phone.min' => '手机号最小为11位字符',
            'captcha.required' => '验证码不能为空',
            'captcha.min' => '验证码最少为4位字符',
        ];
        $validator = Validator::make($input, [
            'phone' => 'required|string|max:11|min:11',
            'captcha' => 'required|min:4',
        ], $messages);

        if($validator->fails())
        {
            return errBack($validator->errors()->first(), 400);
        }

        $areaCode = $input['area_code'] ?? 86;
        $verify = Verification::where('account', $input['phone'])
            ->where('channel', 'sms')
            ->where('area_code', $areaCode)
            ->where('code', $input['captcha'])
            ->orderby('id', 'desc')
            ->first();
        if(!$verify)
        {
            // return errBack('验证码错误或者已失效', 401);
        }

        $headerList = $request->header();

        // 判断手机号是否存在
        $userInfo = $userModel->where(['phone'=>$input['phone']])->first();
        if (!$userInfo)
        {
            $imCode = makeImCode(12);
            $headimg = config('user.headimg');
            $user = User::create($input);
            $user->update(['nickname' => 'im'.$user->id, 'im_number' => $imCode, 'headimg' => $headimg]);
            if($user !==false)
            {
                // 加入到注册队列中
                RegisterTask::dispatch(['user_id'=>$user->id]);

                $userInfo = $userModel->find($user->id);
                $userInfo->api_token = $user->createToken($input['phone'])->accessToken->token;
                $userInfo->save();
                $userInfo->is_new = 1;

                // 判断是否有登录权限，或者是否需要短信验证码验证
                $loginPurview = $ImDeviceModel->isLoginPurview($userInfo, 2,  $headerList);
                if ($loginPurview['code'] == 1)
                {
                    return errBack($loginPurview['msg']);
                }

                if ($loginPurview['code'] == 0 && empty($loginPurview['data']))
                {
                    $ImDeviceModel->addDevice($userInfo, $headerList);
                }

                $userInfo->is_sms_device = !empty($loginPurview['data']) ? 1 : 0; // 需要短信验证

                return okBack($userInfo);
            }
        }
        else
        {
            if ($userInfo->status == 0)
            {
                return errBack('你的账号已被封禁');
            }

            if ($userInfo->area_code != $areaCode)
            {
                return errBack('请选择正确的区号');
            }

            // 判断是否有登录权限，或者是否需要短信验证码验证
            $loginPurview = $ImDeviceModel->isLoginPurview($userInfo, 2,  $headerList);
            if ($loginPurview['code'] == 1)
            {
                return errBack($loginPurview['msg']);
            }

            if ($loginPurview['code'] == 0 && empty($loginPurview['data']))
            {
                $ImDeviceModel->addDevice($userInfo, $headerList);
            }

            $userInfo->is_new = 0;
            $userInfo->is_sms_device = !empty($loginPurview['data']) ? 1 : 0; // 需要短信验证

            return okBack($userInfo);
        }
    }

    /**
     * 获取token
     */
    public function login(Request $request, ImDevice $ImDeviceModel,user $userModel)
    {
        $areaCode = $input['area_code'] ?? 86;
        $headerList = $request->header();
        if(Auth::attempt(['phone' => request('phone'), 'password' => request('password')]))
        {
            $user = Auth::user();
            if ($user->status == 0)
            {
                return errBack('你的账号已被封禁');
            }

            $userInfo = $userModel->find($user->id);
            if ($userInfo->area_code != $areaCode)
            {
                return errBack('请选择正确的区号');
            }

            // 判断是否有登录权限，或者是否需要短信验证码验证
            $loginPurview = $ImDeviceModel->isLoginPurview($user, 1,  $headerList);
            if ($loginPurview['code'] == 1)
            {
                return errBack($loginPurview['msg']);
            }

            if ($loginPurview['code'] == 0 && empty($loginPurview['data']))
            {
                $ImDeviceModel->addDevice($user, $headerList);
            }

            $userInfo->is_sms_device = !empty($loginPurview['data']) ? 1 : 0; // 需要短信验证

            return okBack('登录成功', $userInfo);
        }
        else
        {
            return errBack('账号密码错误！');
        }
    }


    /** 获取登录用户信息
     * @return \Illuminate\Http\JsonResponse
     */
    public function user()
    {
        $user = Auth::user();
        $user->is_password = Redis::get("user_set_{$user->id}") ?? 0;
        $user->notice = $user->notice()->first();
        $user->secrecy = $user->secrecy()->first();
        $imUserCondition = new ImUserCondition();
        $user->condition = $imUserCondition->select('id', 'user_id', 'expired_at', 'condition_id')->with(['status'])->where(['user_id'=>$user->id])->first();


        return okBack('用户信息', $user);
    }

    /**
     * @desc 忘记密码
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse
     * @author zhouzhou
     * @time 2021/11/30 14:45
     */
    public function forgetPassword(Request $request)
    {
        $input = $request->all();
        $messages = [
            'phone.required' => '手机号不能为空',
            //'phone.unique'    => '手机号已被注册',
            'phone.max' => '手机号最大为11位字符',
            'phone.min' => '手机号最小为11位字符',
            'password.required' => '密码不能为空',
            'password.min' => '密码最少为6位字符',
        ];
        $validator = Validator::make($input, [
            'phone' => 'required|string|max:11|min:11',
            'password' => 'required|string|min:6',
        ], $messages);

        if($validator->fails())
        {
            return errBack($validator->errors()->first(), 400);
        }

        $user = User::where(['phone'=>$input['phone']])->first();
        if(!$user)
        {
            return errBack('该手机号不存在', 401);
        }
        $user->password = bcrypt($input['password']);
        if($user->save())
        {

            return okBack('密码修改成功');
        }

        return errBack('密码修改失败', 400);
    }

    /**
     * 获取老用户验证码
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function getCaptcha(Request $request)
    {
        $input = $request->all();
        $messages = [
            'phone.required' => '手机号不能为空',
            'phone.max' => '手机号最大为11位字符',
            'phone.min' => '手机号最小为11位字符',
        ];
        $validator = Validator::make($input, [
            'phone' => 'required|string|max:11|min:11',
        ], $messages);
        if($validator->fails())
        {
            return errBack($validator->errors()->first(), 400);
        }
        $phrase = new PhraseBuilder(6, '0123456789');
        $CaptchaBuilder = new CaptchaBuilder(null, $phrase);
        $captcha = $CaptchaBuilder->getPhrase();
        $input['code'] = $captcha;
        $input['channel'] = 'sms';
        $input['account'] = $input['phone'];
        $input['area_code'] = $input['area_code'] ?? 86;
        $ver = Verification::create($input);
        try
        {
            if($ver !==false)
            {
                $success['phone'] = $input['phone'];
                $success['captcha'] = $captcha;
                $sms = new EasySms(config('sms'));
                $sms->send($input['phone'], [
                    'template' => 'SMS_152145501',
                    'data' => [
                        'code' => $captcha
                    ],
                ]);
                return okBack('验证码发送成功', $success );
            }
            else
            {
                return errBack('验证码发送失败', 400);
            }
        }catch(\Exception $exception)
        {
            \Log::error($exception);
            return errBack('验证码发送失败', 400);
        }
    }

    /**
     * @desc 重置密码
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse
     * @author zhouzhou
     * @time 2021/11/30 14:45
     */
    public function resetPassword(Request $request)
    {
        $input = $request->all();
        $messages = [
            'phone.required' => '手机号不能为空',
            'phone.max' => '手机号最大为11位字符',
            'phone.min' => '手机号最小为11位字符',
            'password.required' => '密码不能为空',
            'password.min' => '密码最少为6位字符',
            'new_password.required' => '新密码不能为空',
            'new_password.min' => '新密码最少为6位字符',
        ];
        $validator = Validator::make($input, [
            'phone' => 'required|string|max:11|min:11',
            'password' => 'required|string|min:6',
            'new_password' => 'required|string|min:6',
        ], $messages);

        if($validator->fails())
        {
            return errBack($validator->errors()->first(), 400);
        }

        if(Auth::attempt(['phone' => request('phone'), 'password' => request('password')]))
        {

            $user = User::where('phone', $input['phone'])->first();
            if(!$user)
            {
                return errBack('该手机号不存在', 401);
            }

            $user->password = bcrypt($input['new_password']);
            if($user->save())
            {

                return okBack('密码修改成功');
            }
        }
        else
        {
            return errBack('旧密码错误', 400);
        }
    }

    /**
     * @desc 设备号管理
     * @param Request $request
     * @param ImDevice $ImDeviceModel
     * @return \Illuminate\Http\JsonResponse
     * @author zhouzhou
     * @time 2021/11/30 15:46
     */
    public function deviceList(Request $request, ImDevice $ImDeviceModel)
    {
        $user = $request->user();
        $userId = $user->id;
        $list = $ImDeviceModel->select('id', 'user_id', 'device_id', 'system_version', 'terminal', 'created_at')->where(['user_id'=>$userId, 'status'=>1])
            ->orderBy('id', 'desc')
            ->get();

        return okBack($list);
    }

    /**
     * @desc 修改手机号
     * @param Request $request
     * @return mixed
     * @author zhouzhou
     * @time 2021/12/6
     */
    public function modifyPhone(Request $request, user $userModel)
    {
        $user = auth()->user();
        $input = $request->all();
        $messages = [
            'phone.required' => '手机号不能为空',
            'phone.max' => '手机号最大为11位字符',
            'phone.min' => '手机号最小为11位字符',
            'captcha.required' => '验证码不能为空',
            'captcha.min' => '验证码最少为4位字符',
        ];
        $validator = Validator::make($input, [
            'phone' => 'required|string|max:11|min:11',
            'captcha' => 'required|min:4',
        ], $messages);
        if($validator->fails())
        {
            return errBack($validator->errors()->first(), 400);
        }

        $areaCode = $input['area_code'] ?? 86;
        $verify = Verification::where('account', $input['phone'])
            ->where('channel', 'sms')
            ->where('area_code', $areaCode)
            ->where('code', $input['captcha'])
            ->orderby('id', 'desc')
            ->first();
        if(!$verify)
        {
            return errBack('验证码错误或者已失效', 401);
        }

        $userPhone = $userModel->where(['phone'=>$input['phone']])->first();
        if ($userPhone)
        {
            return errBack('手机号已存在，请换一个手机号', 401);
        }

        $user->phone = $input['phone'];
        $flag = $user->save();
        if ($flag)
        {
            return okBack($user);
        }
        else
        {
            return errBack('更换失败');
        }
    }

    /**
     * @desc 验证验证码是否正确
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse
     * @author zhouzhou
     * @time 2021/11/30 14:45
     */
    public function checkCaptcha(Request $request)
    {
        $input = $request->all();
        $messages = [
            'phone.required' => '手机号不能为空',
            //'phone.unique'    => '手机号已被注册',
            'phone.max' => '手机号最大为11位字符',
            'phone.min' => '手机号最小为11位字符',
            'captcha.required' => '验证码不能为空',
            'captcha.min' => '验证码最少为4位字符',
        ];
        $validator = Validator::make($input, [
            'phone' => 'required|string|max:11|min:11',
            'captcha' => 'required|min:4',
        ], $messages);

        if($validator->fails())
        {
            return errBack($validator->errors()->first(), 400);
        }

        $areaCode = $input['area_code'] ?? 86;
        $verify = Verification::where('account', $input['phone'])
            ->where('channel', 'sms')
            ->where('area_code', $areaCode)
            ->where('code', $input['captcha'])
            ->orderby('id', 'desc')
            ->first();
        if(!$verify)
        {
            return errBack('验证码错误或者已失效', 401);
        }

        return okBack('验证成功');
    }

    /**
     * @desc 登录设备验证手机短信
     * @param Request $request
     * @param ImDevice $ImDeviceModel
     * @param User $userModel
     * @return \Illuminate\Http\JsonResponse
     * @author zhouzhou
     * @time 2021/12/15 18:24
     */
    public function verifyDeviceSms(Request $request, ImDevice $ImDeviceModel)
    {
        $user = auth()->user();
        $headerList = $request->header();
        $ImDeviceModel->updateDevice($user, $headerList);

        return okBack();

    }

}
